package com.changhai.diabetes.dao;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException;
import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.arcsoft.frameworkcommons.dao.BaseDao;
import com.changhai.diabetes.util.MySqlMapClientFactoryBean;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapExecutor;
import com.ibatis.sqlmap.client.event.RowHandler;

public class BaseDaoImpl extends SqlMapClientDaoSupport implements BaseDao {
	private static Map<String, SqlMapClientTemplate> templateMap = null;

	/**
	 * 初始化SqlMapClientTemplate的map
	 */
	public BaseDaoImpl() {
		if (templateMap == null) {
			templateMap = new HashMap<String, SqlMapClientTemplate>();
			for (Object o : MySqlMapClientFactoryBean.getSqlMapClientMap().keySet()) {
				SqlMapClient sqlMapClient = MySqlMapClientFactoryBean.getSqlMapClientMap().get(o);
				DataSource ds = MySqlMapClientFactoryBean.getDataSourceMap().get(o);
				SqlMapClientTemplate template = new SqlMapClientTemplate();
				template.setSqlMapClient(sqlMapClient);
				template.setDataSource(ds);
				template.afterPropertiesSet();
				templateMap.put(o.toString(), template);
			}
		}
	}

	public void test() {
		// SqlMapClientTemplate ddd = super.getSqlMapClientTemplate();
	}

	@SuppressWarnings("unchecked")
	public <T> T execute(SqlMapClientCallback action) throws DataAccessException {
		return (T) getSqlMapClientTemplate().execute(action);
	}

	@SuppressWarnings("unchecked")
	public <T> T queryForObject(String statementName) throws DataAccessException {
		return (T) getSqlMapClientTemplate().queryForObject(statementName);
	}

	@SuppressWarnings("unchecked")
	public <T> T queryForObject(final String statementName, final Object parameterObject) throws DataAccessException {
		return (T) getSqlMapClientTemplate().queryForObject(statementName, parameterObject);
	}

	@SuppressWarnings("unchecked")
	public <T> T queryForObject(final String statementName, final Object parameterObject, final Object resultObject)
			throws DataAccessException {
		return (T) getSqlMapClientTemplate().queryForObject(statementName, parameterObject, resultObject);
	}

	public List<?> queryForList(String statementName) throws DataAccessException {
		return queryForList(statementName, null);
	}

	public List<?> queryForList(final String statementName, final Object parameterObject) throws DataAccessException {
		return getSqlMapClientTemplate().queryForList(statementName, parameterObject);
	}

	public List<?> queryForList(String statementName, int skipResults, int maxResults) throws DataAccessException {
		return queryForList(statementName, null, skipResults, maxResults);
	}

	public List<?> queryForList(final String statementName, final Object parameterObject, final int skipResults,
			final int maxResults) throws DataAccessException {
		return getSqlMapClientTemplate().queryForList(statementName, parameterObject, skipResults, maxResults);
	}

	public void queryWithRowHandler(String statementName, RowHandler rowHandler) throws DataAccessException {
		queryWithRowHandler(statementName, null, rowHandler);
	}

	public void queryWithRowHandler(final String statementName, final Object parameterObject,
			final RowHandler rowHandler) throws DataAccessException {
		getSqlMapClientTemplate().queryWithRowHandler(statementName, parameterObject, rowHandler);
	}

	public Map<?, ?> queryForMap(final String statementName, final Object parameterObject, final String keyProperty)
			throws DataAccessException {
		return getSqlMapClientTemplate().queryForMap(statementName, parameterObject, keyProperty);
	}

	public Map<?, ?> queryForMap(final String statementName, final Object parameterObject, final String keyProperty,
			final String valueProperty) throws DataAccessException {
		return getSqlMapClientTemplate().queryForMap(statementName, parameterObject, keyProperty, valueProperty);
	}

	public <T> T insert(String statementName) throws DataAccessException {
		return (T) getSqlMapClientTemplate().insert(statementName, null);
	}

	@SuppressWarnings("unchecked")
	public <T> T insert(final String statementName, final Object parameterObject) throws DataAccessException {
		return (T) getSqlMapClientTemplate().insert(statementName, parameterObject);
	}

	public int update(String statementName) throws DataAccessException {
		return update(statementName, null);
	}

	public int update(final String statementName, final Object parameterObject) throws DataAccessException {
		Integer result = (Integer) execute(new SqlMapClientCallback() {
			public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
				return new Integer(executor.update(statementName, parameterObject));
			}
		});
		return result.intValue();
	}

	public void update(String statementName, Object parameterObject, int requiredRowsAffected)
			throws DataAccessException {

		int actualRowsAffected = update(statementName, parameterObject);
		if (actualRowsAffected != requiredRowsAffected) {
			throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(statementName, requiredRowsAffected,
					actualRowsAffected);
		}
	}

	public int delete(String statementName) throws DataAccessException {
		return delete(statementName, null);
	}

	public int delete(final String statementName, final Object parameterObject) throws DataAccessException {

		Integer result = (Integer) execute(new SqlMapClientCallback() {
			public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
				return new Integer(executor.delete(statementName, parameterObject));
			}
		});
		return result.intValue();
	}

	public void delete(String statementName, Object parameterObject, int requiredRowsAffected)
			throws DataAccessException {

		int actualRowsAffected = delete(statementName, parameterObject);
		if (actualRowsAffected != requiredRowsAffected) {
			throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(statementName, requiredRowsAffected,
					actualRowsAffected);
		}
	}

	public static Map<String, SqlMapClientTemplate> getTemplateMap() {
		return templateMap;
	}

	public static void setTemplateMap(Map<String, SqlMapClientTemplate> templateMap) {
		BaseDaoImpl.templateMap = templateMap;
	}

}
